package com.pjmike.netty.utils;

import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.util.zip.CRC32;

@Slf4j
public class Crc32Util {
    /**
     * @return boolean
     * @Author bj
     * @Description //从字节流报文校验报文crc32加密
     * @Date 11:24 2021/1/10
     * @Param [byteBuf]
     **/
    public static boolean checkMessageFromByteBuf(ByteBuf byteBuf) {
        return checkMessageFromByteBuf(byteBuf, 5);
    }

    /**
     * @return boolean
     * @Author bj
     * @Description //从字节流报文校验报文crc32加密
     * @Date 11:24 2021/1/10
     * @Param [byteBuf, crcLastIndex]
     **/
    public static boolean checkMessageFromByteBuf(ByteBuf byteBuf, int crcLastIndex) {
        long crc32Value = getMessageCrc32FromByteBuf(byteBuf, crcLastIndex);
        byteBuf.markReaderIndex();
        byteBuf.skipBytes(byteBuf.readableBytes() - crcLastIndex);
        long requestCrc32 = byteBuf.readUnsignedInt();
        boolean ret = crc32Value == requestCrc32;
        if(!ret){
            log.error("crc校验未通过，系统计算值={}，报文请求过来的值，{}",crc32Value,requestCrc32);
        }
        byteBuf.resetReaderIndex();
        return ret;
    }

    /**
     * @return boolean
     * @Author bj
     * @Description //计算获取byteBuf中的crc32
     * @Date 10:29 2021/1/11
     * @Param [byteBuf, crcLastIndex]
     **/
    public static long getMessageCrc32FromByteBuf(ByteBuf byteBuf, int crcLastIndex) {
        byte[] bytes = new byte[byteBuf.readableBytes() - crcLastIndex];
        byteBuf.getBytes(0,bytes);
        return getMessageCrc32ByBytes(bytes,0);
    }

    /**
     * @return boolean
     * @Author bj
     * @Description //计算bytes的crc32值
     * @Date 10:29 2021/1/11
     * @Param [bytes, crcLastIndex]
     **/
    public static long getMessageCrc32ByBytes(byte[] bytes, int crcLastIndex) {
        int length = bytes.length-crcLastIndex;
        byte[] crcBytes = new byte[length];
        System.arraycopy(
                bytes,
                0, crcBytes,0, length);
        CRC32 crc32 = new CRC32();
        crc32.update(crcBytes);
        return crc32.getValue();
    }

    public static void main(String[] args) {
        String str = "40:06:A0:58:97:B6";
        CRC32 crc32 = new java.util.zip.CRC32();
        crc32.update(str.getBytes());
        System.out.println("CRC32:" + Long.toHexString(crc32.getValue()));
    }
}
